package com.woniu.adopt_web.controller;

import com.alibaba.fastjson.JSONArray;
import com.github.pagehelper.PageInfo;
import com.google.code.kaptcha.Constants;
import com.google.code.kaptcha.Producer;
import com.woniu.adopt_web.common.Constant;
import com.woniu.adopt_web.entity.Message;
import com.woniu.adopt_web.entity.Pet;
import com.woniu.adopt_web.entity.PetCollection;
import com.woniu.adopt_web.service.EmailService;
import com.woniu.adopt_web.service.UserService;
import com.woniu.adopt_web.vo.UserVo;
import org.apache.tomcat.util.http.fileupload.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import org.springframework.web.servlet.mvc.support.RedirectAttributesModelMap;

import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("user")
public class UserController implements Constant {
    private String emailCode;//邮箱验证码 后期换redis

    @Autowired
    private Producer producer;//验证码com.google.code.kaptcha.Producer

    @Autowired
    private EmailService emailService;

    @Autowired
    private UserService userService;

    /**
     * 登录功能
     *
     * @param userVo
     * @param validatecode
     * @param checkAutoLogin
     * @param response
     * @param session
     * @return
     */
    @PostMapping("/login")
    public String login(UserVo userVo, String validatecode, Boolean checkAutoLogin, HttpServletResponse response, HttpSession session) {
        //获得验证码
        String sessionCode = (String) session.getAttribute(Constants.KAPTCHA_SESSION_KEY);
        UserVo login = userService.login(userVo.getUsername(), userVo.getPassword());
        String out = null;
        if (validatecode == null || !validatecode.equalsIgnoreCase(sessionCode)) {
            //验证码错误
            out = "codeError";
        } else if (login == null) {
            out = "passwordError";
        } else if (login.getLocked() == 1) {
            out = "locked";
        } else {
            out = "success";
            //登录成功
            login.setPic(ADOPT_IMG_URL + login.getPic());
            session.setAttribute("loginUser", login);
            //查询未读消息数量
            int result = userService.findUnRead(login.getId());
            session.setAttribute("msgNum", result);
            //自动登录
            if (checkAutoLogin != null) {
                String content = userVo.getUsername() + ":" + userVo.getPassword();

                Cookie cookie = new Cookie("auto", content);
                cookie.setPath("/");
                //存一天
                cookie.setMaxAge(24 * 60 * 60);
                response.addCookie(cookie);
            }
        }

        return out;
    }

    /**
     * 确认登录用户是否存在
     *
     * @param username
     * @return
     */
    @GetMapping("/checkLogin")
    public Map<String, Boolean> checkLogin(String username) {
        UserVo userByName = userService.findUserByName(username);
        boolean b = false;
        if (userByName != null) {
            b = true;
        }
        Map<String, Boolean> map = new HashMap<>();
        map.put("valid", b);
        return map;
    }

    /**
     * 注销方法
     */
    @GetMapping("/logOut")
    public ModelAndView logOut(HttpSession session, HttpServletResponse response) throws IOException {

        session.removeAttribute("loginUser");
        //清空和覆盖cookie的自动登录信息
        Cookie cookie = new Cookie("auto", "");
        cookie.setPath("/");
        cookie.setMaxAge(0);
        response.addCookie(cookie);

        //使用了RestController 无法映射跳转 会直接输出地址字符串 这里用response代替
        //百度了下，可以用ModelAndView
        return new ModelAndView("redirect:/login.html");

    }

    /**
     * 确认注册用户是否存在
     *
     * @param username
     * @return
     */
    @GetMapping("/checkRegister")
    public Map<String, Boolean> checkRegister(String username) {
        UserVo userByName = userService.findUserByName(username);
        boolean b = false;
        if (userByName != null) {
            b = true;
        }
        Map<String, Boolean> map = new HashMap<>();
        map.put("valid", !b);
        return map;
    }

    @PostMapping("/register")
    public String register(UserVo userVo, String code, HttpServletResponse response, HttpSession session) throws IOException {
        //1.获取用户信息
        userVo.setInsertTime(new Date());
        if (!code.equals(emailCode)) {
            return "fail";
        }
        //注册业务逻辑
        int i = userService.addUserByRegister(userVo);
        if (i == 1) {
            UserVo userByName = userService.findUserByName(userVo.getUsername());
            userByName.setPic(ADOPT_IMG_URL + userByName.getPic());
            //登录成功
            session.setAttribute("loginUser", userByName);
            //自动登录
            String content = userVo.getUsername() + ":" + userVo.getPassword();

            Cookie cookie = new Cookie("auto", content);
            cookie.setPath("/");
            //存一天
            cookie.setMaxAge(24 * 60 * 60);
            response.addCookie(cookie);
            return "success";
        }
        return "fail";
    }

    /**
     * 发送方邮件
     *
     * @return
     */
    @Value("${spring.mail.username}")
    private String sender;

    @GetMapping("/registerCode")
    public void registerCode(@RequestParam("email") String email) {
        emailCode = null;
        //随机生成四位数激活吗
        String code = String.valueOf((int) ((Math.random() * 9 + 1) * 1000));
        //这个是接受人的邮箱
        String receiver = email;
        //标题
        String subject = "新用户-蜗牛领养平台";
        //内容
        String content = "<html>\n" +
                "<body>\n" +
                "<h2>尊敬的用户，您好！</h2>\n" +
                "我们即将创建好您的 蜗牛领养平台 账户，验证码：\n" + code +
                "</body>\n" +
                "</html>";
        //模板邮箱
        boolean result = emailService.sendHtml(sender, receiver, subject, content);
        if (result) {
            emailCode = code;
        }
    }

    /**
     * 生成验证码
     *
     * @param response
     * @param request
     * @throws ServletException
     * @throws IOException
     */
    @GetMapping("kaptcha")
    public void kaptcha(HttpServletResponse response, HttpServletRequest request) throws ServletException, IOException {
        response.setHeader("Cache-Control", "no-store,no-cache");
        response.setContentType("image/jpeg");
        //生成文字验证码
        String text = producer.createText();
        //生成图片验证码
        BufferedImage image = producer.createImage(text);
        //保存验证码到session
        request.getSession().setAttribute(Constants.KAPTCHA_SESSION_KEY, text);
        ServletOutputStream out = response.getOutputStream();
        ImageIO.write(image, "jpg", out);
        //用到IO工具包控制开关
        IOUtils.closeQuietly(out);

    }

    /**
     * 修改用户信息
     *
     * @param userVo
     * @param session
     * @return
     * @throws IOException
     */
    @PostMapping("/modify")
    public int modify(UserVo userVo, HttpSession session) throws IOException {
        boolean flag = false;
        if (userVo.getPassword() != null) {
            flag = true;
        }
        int i = userService.modifyUserByUid(userVo);
        UserVo user = userService.findUserByName(userVo.getUsername());
        user.setPic(ADOPT_IMG_URL + user.getPic());
        if (flag) {
            session.setAttribute("loginUser", null);
        } else {
            session.setAttribute("loginUser", user);
        }
        return i;
    }

    /**
     * 得到用户收藏的宠物列表
     *
     * @return
     * @HttpSession
     * @RedirectAttributes 重定向传递参数的方式[SpringMvc3.1新特性]：请求参数携带RedirectAttributes，为其addFlashAttribute，返回modalAndView
     */
    @GetMapping("/showPetColList")
    public ModelAndView showPetColList(HttpSession session, RedirectAttributes redirectAttributes) throws IOException {
        UserVo loginUser = (UserVo) session.getAttribute("loginUser");
        List<Pet> petColListByUid = userService.findPetColListByUid(loginUser.getId());
        ModelAndView personal = new ModelAndView("redirect:/personal.html?2");
        redirectAttributes.addFlashAttribute("petList", petColListByUid);
        return personal;
    }


    @PostMapping("/beVolunteer")
    public void beVolunteer(String message, Integer option, HttpServletResponse resp, HttpSession session) throws IOException {
        //option==0,表示发送新的申请信息       option==1,表示发送修改信息
        //更改逻辑，用户仅发送修改信息或者新增信息，向前台写1表示修改成功，写0表示新增成功，写-1表示操作失败,取消用户的
        UserVo loginUser = (UserVo) session.getAttribute("loginUser");
        Integer uid = loginUser.getId();
        Integer volunteerStatus = loginUser.getVolunteerStatus();
        try {
            if (option == 1) {
                if (volunteerStatus == 2) {
                    userService.updateApply(uid, message, 0);
                    loginUser.setVolunteerStatus(0);
                    session.setAttribute("loginUser", loginUser);
                } else {
                    userService.updateApply(uid, message, null);
                }
                resp.getWriter().print(1);
            } else {
                userService.insertApply(uid, message);
                //更新session里面的申请状态值
                loginUser.setVolunteerStatus(0);
                session.setAttribute("loginUser", loginUser);
                resp.getWriter().print(0);
            }
        } catch (IOException e) {
            e.printStackTrace();
            resp.getWriter().print(2);
        }
    }

    @GetMapping("/getApplyMessage")
    public void getApplyMessage(HttpServletResponse resp, HttpSession session) throws IOException {
        UserVo loginUser = (UserVo) session.getAttribute("loginUser");
        resp.setContentType("text/html;charset=UTF-8");
        Integer uid = loginUser.getId();
        //根据uid得到message
        String message = userService.queryMessageByUid(uid);
        resp.getWriter().print(message);
    }

    /**
     * 获取所有消息
     */
    @GetMapping("/myMessage")
    public ModelAndView myMessage(HttpSession session, RedirectAttributes redirectAttributes) throws IOException {
        UserVo loginUser = (UserVo) session.getAttribute("loginUser");
        List<Message> list = userService.findMessageListByUid(loginUser.getId());
        ModelAndView personal = new ModelAndView("redirect:/personal.html?3");
        redirectAttributes.addFlashAttribute("msgList", list);
        return personal;
    }

    /**
     * readAllMsg
     * 把消息全部已读
     */

    @GetMapping("/readAllMsg")
    public int readAllMsg(@RequestParam(value = "uid") int uid) {
        int i = userService.modifyMessageByUid(uid);
        if (i == 0) {
            return 0;
        } else {
            return 1;
        }
    }

    @GetMapping("/myMessageNum")
    public void myMessageNum(HttpSession session) {
        UserVo login = (UserVo) session.getAttribute("loginUser");
        //查询未读消息数量
        if (login != null) {
            int result = userService.findUnRead(login.getId());
            session.setAttribute("msgNum", result);
        }
    }
}

